package com.ledi.guns.common.exception;

import java.util.Locale;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.mybatis.spring.MyBatisSystemException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.MessageSource;
import org.springframework.context.NoSuchMessageException;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import com.ledi.guns.core.base.tips.ErrorTip;
import com.ledi.guns.core.base.tips.Tip;

@RestControllerAdvice
public class ExceptionResolver {

	private static final Logger log = LoggerFactory.getLogger(ExceptionResolver.class);

	@Resource
	private MessageSource messageSource;

	/**
	 * 应用逻辑异常处理
	 *
	 * @see SysCodeController
	 * @param e
	 *            {code:错误码,message:错误编号}
	 * @return
	 */
	@ExceptionHandler(AppCheckException.class)
	@ResponseStatus(HttpStatus.OK)
	public ErrorTip appException(AppCheckException e) {

		log.debug(e.getMessage());
		String message = "";
		try {
			message = messageSource.getMessage(e.getMessage(), e.getParam(), Locale.getDefault());
		} catch (NoSuchMessageException e2) {
			message = e.getMessage();
		}
		String code = messageSource.getMessage(e.getCode(), null, Locale.getDefault());
		return new ErrorTip(Integer.parseInt(code), message);
	}

	@ExceptionHandler(MyBatisSystemException.class)
	public Tip myBatisSystemException(HttpServletRequest request,
			HttpServletResponse response, MyBatisSystemException e) {

		Throwable cause = e.getCause().getCause();
		if (cause instanceof AppCheckException) {
			response.setStatus(HttpStatus.OK.value());
			return appException((AppCheckException) cause);
		} else {
			log.error(e.getMessage(), e);
			return new ErrorTip(Integer.parseInt("1000"), "数据库异常");
		}
	}

	/**
	 * web传参json解析异常
	 *
	 * @param e
	 * @return
	 */
	@ExceptionHandler(HttpMessageNotReadableException.class)
	@ResponseStatus
	public ErrorTip notReadableException(HttpMessageNotReadableException e) {

		log.debug(e.getMessage(), e);
		String message = messageSource.getMessage("system.web.json.err", null, Locale.getDefault());
		return new ErrorTip(Integer.parseInt("1003"), message);
	}

	/**
	 * 参数验证异常
	 *
	 * @param e
	 * @return
	 */
	@ExceptionHandler(MethodArgumentNotValidException.class)
	@ResponseStatus(HttpStatus.OK)
	public ErrorTip validException(MethodArgumentNotValidException e) {

		String message = e.getBindingResult().getFieldError().getDefaultMessage();
		log.debug(message);
		return new ErrorTip(Integer.parseInt("1002"), message);
	}

	/**
	 * 参数绑定异常
	 *
	 * @param e
	 * @return
	 */
	@ExceptionHandler(BindException.class)
	@ResponseStatus
	public ErrorTip bindException(BindException e) {

		String field = e.getFieldError().getField();
		Object value = e.getFieldError().getRejectedValue();
		String message = messageSource.getMessage("system.web.param.bind.error", new Object[] { field, value },
				Locale.getDefault());
		log.debug(message);
		return new ErrorTip(Integer.parseInt("1009"), message);
	}

	/**
	 * 用户未登录
	 *
	 * @param e
	 * @return
	 */
	@ExceptionHandler(RestSessionException.class)
	@ResponseStatus(HttpStatus.UNAUTHORIZED)
	public ErrorTip LoginException(RestSessionException e) {

		return new ErrorTip(Integer.parseInt("10000"), "登录已超时，请重新登录。");
	}

	@ExceptionHandler(ReplaceException.class)
	@ResponseStatus(HttpStatus.UNAUTHORIZED)
	public ErrorTip LoginException(ReplaceException e) {

		return new ErrorTip(Integer.parseInt("20000"), "您的账号已在其他地方登录，请重新登录。");
	}

	@ExceptionHandler(ChangePassException.class)
	@ResponseStatus(HttpStatus.UNAUTHORIZED)
	public ErrorTip LoginException(ChangePassException e) {

		return new ErrorTip(Integer.parseInt("30000"), "当前账号信息已修改，请重新登录。");
	}

	// /**
	// * JSON解析异常
	// *
	// * @param e
	// * @return
	// */
	// @ExceptionHandler(JSONException.class)
	// @ResponseStatus
	// public RespJson jsonException(JSONException e,BindingResult result) {
	//
	// if(result.hasErrors()){
	// for (FieldError fieldError : result.getFieldErrors()) {
	// fieldError.getField();
	// }
	//
	// }
	//
	// String message = messageSource.getMessage(e.getMessage(), null, Locale.getDefault());
	// log.debug(message);
	// return RespJsonFactory.buildFailure(message, "7001");
	// }

}
